package 校赛.真题;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 挚爱之夕
 * @version 1.0
 * @implSpec 校赛.真题
 * @since 2023 - 03 - 27 - 16:56
 */
public class Client implements SerialPortEventListener {
    //根据自己串口情况定义
    private static final String PORT_NAME = "COM1";
    //根据自己产品波特率设置，不要设置错误。
    private static final int BIT_RATE = 9600;
    public static final int DATA_BITS = SerialPort.DATABITS_8;
    public static final int STOP_BIT = SerialPort.STOPBITS_1;
    public static final int PARITY_BIT = SerialPort.PARITY_NONE;

    private static SerialPort serialPort;
    private static InputStream in;
    private static OutputStream out;
    private static Client commUtil;


    private Client() {

    }

    public static Client getInstance() {
        if (commUtil == null) {
            commUtil = new Client();
            commUtil.init();
        }
        return commUtil;
    }

    public void init() {
        try {
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(PORT_NAME);
            if (portIdentifier.isCurrentlyOwned()) {
                System.out.println("Error: 当前端口已被占用");
            } else if (portIdentifier.getPortType() == 1) {
                serialPort = (SerialPort) portIdentifier.open(PORT_NAME, 1000);
                serialPort.setSerialPortParams(BIT_RATE, DATA_BITS, STOP_BIT, PARITY_BIT);
                in = serialPort.getInputStream();
                out = serialPort.getOutputStream();
                serialPort.addEventListener(this);
                serialPort.notifyOnDataAvailable(true);
            } else {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void serialEvent(SerialPortEvent event) {
        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            receive();
        }
    }


    public String receive() {
        byte[] buffer = new byte[128];
        int data;
        String result = null;
        try {
            int len = 0;
            while ((data = in.read()) > -1) {
                buffer[len++] = (byte) data;
            }
            byte[] copyValue = new byte[len];
            System.arraycopy(buffer, 0, copyValue, 0, len);
            result = ByteArrayToString(copyValue);
            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    public void close() {
        try {
            in.close();
            out.close();
            serialPort.notifyOnDataAvailable(false);
            serialPort.removeEventListener();
            serialPort.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public byte[] hexStrToByteArray(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[str.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String substr = str.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(substr, 16));
        }
        return byteArray;
    }

    public String ByteArrayToString(byte[] by) {
        String str = "";
        for (int i = 0; i < by.length; i++) {
            String hex = Integer.toHexString(by[i] & 0xFF);
            if (hex.length() == 1) {
                hex = "O" + hex;
            }
            str += hex.toUpperCase();
        }
        return str;
    }


    //转化十六进制编码为字符串
    public String toStringHex1(String s) {
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                System.out.println("=========================每一位开始===========");
                System.out.println(baKeyword[i]);
                System.out.println("***************每一位结束**************");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");// UTF-16le:Not
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }


    public static void main(String[] args) {
        //初始化，检测打开串口，将串口信息赋给流信息
        Client client = Client.getInstance();
        System.out.println("开始程序");
        //解析流文件信息，接收信息
        String a = client.receive();
        //将得到的解析数据转换（如将十六转字符串），得到结果
        String i = client.toStringHex1(a);
        //关闭各种
        client.close();


        int count = 0;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        //System.out.println();// new Date()为获取当前系统时间
        count++;
        System.out.println("第" + count + "过磅");
        System.out.println("过磅数据：" + i + "当前时间：" + df.format(new Date()));
        System.out.println();
        System.out.println();
    }
}
